/**
 * Open Provenance Model Vocabulary Javascript Library
 * Paul Groth
 * 
 * 
 */

if (typeof(__OPM_BASE) == 'undefined')
  __OPM_BASE = '';

//Namespace 
var OPM = new Object();

// configuration information
OPM.opmv_namespace = 'http://purl.org/net/opmv/ns#';
OPM.ns_rdf_type = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type';
//Classes
OPM.ns_process = 'http://purl.org/net/opmv/ns#Process';
OPM.ns_artifact = 'http://purl.org/net/opmv/ns#Artifact';
//Edges
OPM.ns_was_performed_by = 'http://purl.org/net/opmv/ns#wasPerformedBy';
OPM.ns_was_controlled_by = 'http://purl.org/net/opm/ns#wasControlledBy';
OPM.ns_used = 'http://purl.org/net/opmv/ns#used';
OPM.ns_was_derived_from = 'http://purl.org/net/opmv/ns#wasDerivedFrom';
OPM.ns_was_generated_by = 'http://purl.org/net/opmv/ns#wasGeneratedBy';
OPM.ns_was_performed_at = 'http://purl.org/net/opmv/ns#wasPerformedAt';

OPM.Graphs = [];

function OPMGraph()
{
	this.processes = {};
	this.agents = {};
	this.artifacts = {};
}

function OPMAgent(id) {
	this.id = id;
	
}

function OPMArtifact(id) {
	this.id = id;
	this.wasGeneratedBy = [];
	this.wasDerivedFrom = [];
	this.inpage = false;
	this.addWasGeneratedBy = function(process) {
		this.wasGeneratedBy[this.wasGeneratedBy.length] = process;
	}
	
	this.addWasDerivedFrom = function (artifact) {
		this.wasDerivedFrom[this.wasDerivedFrom.length] = artifact;
	}
}

function OPMProcess(id) 
{
	this.id = id;
	this.wasControlledBy = [];
	this.used = []
	this.wasPerformedAt = [];
	
	this.addWasControlledBy = function(agent) {
		this.wasControlledBy[this.wasControlledBy.length] = agent;
	}
	
	this.addUsed = function (artifact) {
		this.used[this.used.length] = artifact;
	}
	
	this.addWasPerformedAt = function (time) {
		this.wasPerformedAt[this.wasPerformedAt.length] = time;
	}
}


OPM.opm_start = function()
{
	
	graph = new OPMGraph()
	//.prefix('opmv', 'http://purl.org/net/opmv/ns#')
	content = $().rdf();
	//console.log(content);
	//alert(content.databank.prefix('dc').toString());
	c = content.databank.dump({format:'application/json', serialize: true});
	console.log(c);
	json = $.evalJSON(content.databank.dump({format:'application/json', serialize: true}));
	console.log (json);
	
	for (var key in json) {
		if (json.hasOwnProperty(key)) {
			if (OPM.ns_rdf_type in json[key]) {
				//console.log('Checking RDF Type')
				types = json[key][OPM.ns_rdf_type];
				for (type in types) {
					console.log(types[type]);
					if (types[type]['value'] == OPM.ns_process) {
						//console.log('Found a Process');
						process = new OPMProcess(key);
						graph.processes[key] = process;
					}
					else if (types[type]['value'] == OPM.ns_artifact) {
						artifact = new OPMArtifact(key);
						artifact.inpage = true;
						graph.artifacts[key] = artifact;
						
					}
				}
			}
			if (OPM.ns_used in json[key]) {
					console.log("Used Edge");
					edges = json[key][OPM.ns_used];
					for (e in edges) {
						p = graph.processes[key];
						if (edges[e]['value'] in graph.artifacts) {
							p.addUsed(graph.artifacts[edges[e]['value']]);	
						}
						else {
						    console.log(edges[e]['value'])
							a = new OPMArtifact(edges[e]['value']);
							//a.inpage = true;
							graph.artifacts[edges[e]['value']] = a;
							p.addUsed(a);
							
					}
				}
			}
			
			if (OPM.ns_was_performed_by in json[key] ) {
					console.log("WasPerformedBy");
					edges = json[key][OPM.ns_was_performed_by];
					for (e in edges) {
						p = graph.processes[key];
						if (edges[e]['value'] in graph.agents) {
							p.addWasControlledBy(graph.agents[edges[e]['value']]);	
						}
						else {
						    console.log(edges[e]['value'])
							a = new OPMAgent(edges[e]['value']);
							graph.agents[edges[e]['value']] = a;
							p.addWasControlledBy(a);
							
					}
				}
			}
			
			if (OPM.ns_was_controlled_by in json[key] ) {
					console.log("WasControlledBy");
					edges = json[key][OPM.ns_was_controlled_by];
					for (e in edges) {
						p = graph.processes[key];
						if (edges[e]['value'] in graph.agents) {
							p.addWasControlledBy(graph.agents[edges[e]['value']]);	
						}
						else {
						    console.log(edges[e]['value'])
							a = new OPMAgent(edges[e]['value']);
							graph.agents[edges[e]['value']] = a;
							p.addWasControlledBy(a);
							
					}
				}
			}
			
			if (OPM.ns_was_derived_from in json[key]) {
					console.log("WasDerivedFrom Edge");
					edges = json[key][OPM.ns_was_derived_from];
					for (e in edges) {
						a = graph.artifacts[key];
						if (edges[e]['value'] in graph.artifacts) {
							a.addWasDerivedFrom(graph.artifacts[edges[e]['value']]);	
						}
						else {
						    //console.log(a.id + " " + edges[e]['value'])
							na = new OPMArtifact(edges[e]['value']);
							na.inpage = true;
							graph.artifacts[edges[e]['value']] = na;
							a.addWasDerivedFrom(na);
							
					}
				}
			}
			
			if (OPM.ns_was_generated_by in json[key]) {
					console.log("WasGeneratedBy Edge");
					edges = json[key][OPM.ns_was_generated_by];
					for (e in edges) {
						a = graph.artifacts[key];
						if (edges[e]['value'] in graph.processes) {
							a.addWasGeneratedBy(graph.processes[edges[e]['value']]);	
						}
						else {
						    console.log(a.id + " " + edges[e]['value'])
							p = new OPMProcess(edges[e]['value']);
							graph.processes[edges[e]['value']] = p;
							a.addWasGeneratedBy(p);
					}
				}
			}
			
			
		}
	}
	
	OPM.Graphs[length] = graph;
	
	//var aImages = document.getElementsByTagName("img");
	//for (var i=0;i<aImages.length;i++) {
	//		EXIF.getData(aImages[i],  OPM.processImage);
	//}
	
	//OPM.processImage(graph);
	//console.log(graph);
	
	OPM.drawGraph(graph);

}


OPM.processImage = function()
{
   console.log("yes!!");
   graph = OPM.Graphs[0];

   $('img').each(function(index) {
	
		
	
		 console.log("found an image " + this);
		 var metadata = EXIF.pretty(this);
		 console.log(metadata);
		 
		 var img = this.src;
		 var img_art = new OPMArtifact(img);
		 img_art.inpage = true;
		 graph.artifacts[img] = img_art;
		 
		 
		 var modifiedDate = EXIF.getTag(this,"DateTime");
		 var software = EXIF.getTag(this, "Software");
		 var software_proc = new OPMProcess(software);
		 software_proc.addWasPerformedAt(modifiedDate);
		 
		 graph.processes[software] = software_proc;
		 
		 img_art.addWasGeneratedBy(software_proc)
		 
		 var copyright = EXIF.getTag(this,"Copyright");
		 
		 var copyright_art = new OPMArtifact(copyright);
		 graph.artifacts[copyright] = copyright_art;
		 img_art.addWasDerivedFrom(copyright_art);
		 
		 
		 
		 
		 //camera = EXIF.getTag(this,"Model");
	});
	
	OPM.drawGraph(graph);
}



OPM.drawGraph = function(graph)
{

	
	
	
	var viz = [];
	
	var root = {'id':'root', 'name':'Page','data':{"$type":"triangle",
						"$dim":"20"}, 'adjacencies':[]};
	viz[viz.length] = root;
	
	for (process in graph.processes) {
		var p = graph.processes[process];
		var node = {};
		var name = p.id;
		node["id"] = name;
		node["name"] = name
		node["data"] = {"$dim":"20"};
		var adj = [];
		for (used in p.used) {
		    adj[adj.length] = p.used[used]['id'];
		}
		for (wcb in p.wasControlledBy) {
		    adj[adj.length] = p.wasControlledBy[wcb]['id'];
		}
		for (wpa in p.wasPerformedAt) {
			adj[adj.length] = p.wasPerformedAt[wpa];
			var dnode = {};
			dnode["id"] = p.wasPerformedAt[wpa];
			dnode["name"] = p.wasPerformedAt[wpa];
			dnode["data"] = {};
			dnode["adjacencies"] = [];
			viz[viz.length] = dnode;
		}
		
		node["adjacencies"] = adj;
		
		viz[viz.length] = node;
	}
	
	for (artifact in graph.artifacts) {
		var a = graph.artifacts[artifact];
		var node = {};
		node["id"] = a.id;
		node["name"] = a.id;
		node["data"] = {"$type":"triangle",
						"$dim":"20"};
		var adj = [];
		if (a.inpage == true) {
			adj[adj.length] = 'root';
		}
		for (wdf in a.wasDerivedFrom) {
		    console.log(a.wasDerivedFrom[wdf]['id']);
		    adj[adj.length] = a.wasDerivedFrom[wdf]['id'];
		}
		for (wgb in a.wasGeneratedBy) {
		    console.log(a.wasGeneratedBy[wgb]['id']);
		    adj[adj.length] = a.wasGeneratedBy[wgb]['id'];
		}
		
		node["adjacencies"] = adj;
		
		viz[viz.length] = node;
	}
	
	for (agent in graph.agents) {
		var ag = graph.agents[agent];
		var node = {};
		node["id"] = ag.id;
		node["name"] = ag.id;
		node["data"] = {};
		var adj = [];
		/*for (used in p.used) {
		    adj[adj.length] = p.used[used]['id'];
		}*/
		node["adjacencies"] = adj;
		
		viz[viz.length] = node;
	}
	
	
	
	console.log(viz);

		
	
	var infovizdiv = document.createElement("div");
	infovizdiv.id = "infovis";
	document.body.appendChild(infovizdiv);
	
	var canvas = new Canvas('mycanvas', {  
    	//Where to inject the canvas. Any div container will do.  
    	'injectInto':'infovis',  
    	//width and height for canvas. Default's to 200.  
    	'width': 500,  
    	'height':400  
 	}); 
 	
 	
  	var rgraph= new Hypertree(canvas,  {  
		//interpolation type, can be linear or polar  
		//interpolation: 'polar',  
		//parent-children distance  
		//levelDistance: 100,  
		//Set node/edge styles  
		Node: {  
	  		color: '#ccddee',
	  		overridable: true,
	  	
		},  
		Edge: {  
		 overridable: true, 
			color: '#772277'
	  		//lineWidth: 2
		},  
		//Add a controller to make the tree move on click.  
		
   		 onCreateLabel: function(domElement, node) {  
   		    
   		    var name = node.name
			var index = node.name.indexOf(window.location.href)
			if (index != -1) {
				name = node.name.substring(window.location.href.length);
			}
      		domElement.innerHTML = name;  
      		domElement.onclick = function() {  
         		rgraph.onClick(node.id);  
      		};  
    	 },  
    	 
    	 onPlaceLabel: function(tag, node) {  
    	 	var width = tag.offsetWidth;  
      		var intX = parseInt(tag.style.left);  
      		intX -= width / 2;  
      		tag.style.left = intX + 'px';  
    	}  
  });  
  
		//load tree from tree data.  
	rgraph.loadJSON(viz);  
	//compute positions and plot  
	rgraph.refresh(); 
	
}

OPM.whatup = function()
{
	console.log("What's up!");
}

/*OPM.load = function()
{
    var s = document.createElement("script");
    s.type = 'text/javascript';
    s.src=__OPM_BASE+"/jquery/jquery-1.3.2.js";
    
    document.getElementsByTagName('head')[0].appendChild(s);
    
     s = document.createElement("script");
    s.type = 'text/javascript';
    s.src=__OPM_BASE+"/jquery/dist/js/jquery.rdfquery.core-1.0.js";
    
    document.getElementsByTagName('head')[0].appendChild(s);
    
    s = document.createElement("script");
    s.type = 'text/javascript';
    s.src=__OPM_BASE+"/jquery/dist/js/jquery.rdfquery.rdfa-1.0.js";
    
    document.getElementsByTagName('head')[0].appendChild(s);
    
	s = document.createElement("script");
    s.type = 'text/javascript';
    s.src=__OPM_BASE+"/jquery/dist/js/jquery.rdfquery.rules-1.0.js";
    
    document.getElementsByTagName('head')[0].appendChild(s);
    
    s = document.createElement("script");
    s.type = 'text/javascript';
    s.src=__OPM_BASE+"/jquery/jquery.json-2.2.min.js";
    
    document.getElementsByTagName('head')[0].appendChild(s);
   
    
    s = document.createElement("script");
    s.type = 'text/javascript';
    s.src=__OPM_BASE+"/Jit/jit.js";
    
    document.getElementsByTagName('head')[0].appendChild(s);
    
    
    s = document.createElement("script");
    s.type = 'text/javascript';
    s.src=__OPM_BASE+"exif.js";
    
    document.getElementsByTagName('head')[0].appendChild(s);
    
        s = document.createElement("script");
    s.type = 'text/javascript';
    s.src=__OPM_BASE+"binaryajax.js";
    
    document.getElementsByTagName('head')[0].appendChild(s);
    
    alert("loaded")
    
    OPM.opm_start()
    // add it to the document tree, load it up!
    
}

OPM.load()*/

